package it.gtd.swimpool.model.business;

import it.gtd.swimpool.model.entity.Feedback;
import it.gtd.swimpool.model.entity.Rating;
import it.gtd.swimpool.model.entity.Skill;
import it.gtd.swimpool.model.entity.User;
import org.jetbrains.annotations.Nullable;

import javax.ejb.LocalBean;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.TypedQuery;
import java.util.List;

import static com.google.common.base.Preconditions.*;

@Stateless
@LocalBean
public class FeedbackManager {
    @PersistenceContext
    private EntityManager entityManager;

    public Feedback sendFeedback(User sender, User target, Skill skill, Rating rating, @Nullable String comment) {
        checkNotNull(sender, "sender can't be null");
        checkNotNull(target, "target can't be null");
        checkNotNull(skill, "skill can't be null");
        checkNotNull(rating, "rating can't be null");
        checkArgument(entityManager.contains(sender), "Sender User is not a managed entity");
        checkArgument(entityManager.contains(target), "Target User is not a managed entity");
        checkArgument(entityManager.contains(skill), "Target skill is not a managed entity");
        checkArgument(target.getSkills().contains(skill), "Target User doesn't contains given skill");
        checkArgument(!sender.equals(target), "Sender can't send feedback to himself");

        TypedQuery<User> selectAuthors = entityManager.createNamedQuery("Feedback.authorsForSkillAndTarget", User.class);
        selectAuthors.setParameter("skill", skill);
        selectAuthors.setParameter("target", target);

        List<User> previousAuthors = selectAuthors.getResultList();
        checkArgument(!previousAuthors.contains(sender), "This user has already sent a feedback for that user and skill");

        Feedback feedback = new Feedback(sender, target, skill);
        feedback.setRating(rating);
        if (comment != null) feedback.setText(comment);
        entityManager.persist(feedback);

        checkState(entityManager.contains(feedback), "Feedback is not a managed entity");

        return feedback;
    }

    public List<Feedback> getFeedbacks(User target, @Nullable Skill skill) {
        checkNotNull(target, "target can't be null");
        return null == skill ?
                entityManager.createNamedQuery("Feedback.byTarget").setParameter("target", target).getResultList() :
                entityManager.createNamedQuery("Feedback.byTargetAndSkill").setParameter("target", target).setParameter("skill", skill).getResultList();
    }
}
